/*
 * Copyright (c) 2012 Aleksander Zotov, Benedikt Markt, Aliaksei Babkovich
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 *  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package user;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import utils.InvalidInputException;
import utils.UserNotFoundException;
import database.DatabaseManager;

/**
 * This holds all registered Users and contains methods to modify them
 * 
 * @author Benedikt Markt
 * @see User TODO Remove resetPassword(username) from draft
 */

public class UserManager {

	private static UserManager instance = new UserManager();

	/**
	 * A list that holds all registered users
	 */
	private List<User> users = new ArrayList<User>();

	private UserManager() {
		DatabaseManager dbMan = new DatabaseManager();
		users = dbMan.loadUsers();
		if (!isExistingUser("Admin")) {
			try {
				createUser("Admin");
				User admin = getUser("Admin");
				admin.setAdminState(true);
				admin.setPassword("SatAdmin1*");
				dbMan.storeUser(admin);

			} catch (InvalidInputException e) {
				// e.printStackTrace();
			} catch (UserNotFoundException e) {
				// e.printStackTrace();
			}
		}
		organizeFolders();
	}

	public static UserManager getInstance() {
		return instance;
	}

	/**
	 * Creates a new user
	 * 
	 * @param username
	 *            the name of the user to create
	 */
	public void createUser(String username) throws InvalidInputException {
		User newUser = new User(username);
		users.add(newUser);

		DatabaseManager dbMan = new DatabaseManager();
		dbMan.storeUser(newUser);

		createUserFolder(username);
	}

	/**
	 * Deletes an user from the list and database
	 * 
	 * @param username
	 *            name of the user to delete
	 */
	public void deleteUser(String username) {
		for (int i = 0; i < users.size(); i++) {
			if (users.get(i).getName().equals(username)) {
				DatabaseManager dbMan = new DatabaseManager();
				dbMan.deleteUser(users.get(i));
				users.remove(i);
			}
		}
		organizeFolders();
	}

	/**
	 * Checks whether an user name is registered or not
	 * 
	 * @param username
	 *            name of the user to check for
	 * @return true if the user is registered, otherwise false
	 */
	public Boolean isExistingUser(String username) {
		if (users != null) {
			for (User u : users) {
				if (u.getName().equals(username)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Checks an username/password combination
	 * 
	 * @param username
	 *            name of the user
	 * @param password
	 *            the users password
	 * @return true if credentials are correct, otherwise false
	 */
	public Boolean isCorrectLogin(String username, String password) {
		for (User u : users) {
			if (u.getName().equals(username)) {
				if (u.getPassword().equals(password)) {
					return true;
				}
			}
		}
		return false;
	}

	public User getUser(String username) throws UserNotFoundException {
		for (User u : users) {
			if (u.getName().equals(username)) {
				return u;
			}
		}
		throw new UserNotFoundException();
	}

	/**
	 * Returns a list of all users
	 * 
	 * @return the list of all users
	 */
	public List<User> getUsers() {
		return users;
	}

	/**
	 * Creates a folder for the given user
	 * 
	 * TODO add to draft
	 * 
	 * @param username
	 *            the name of the user and the folder
	 */
	private void createUserFolder(String username) {
		File folder = new File(".\\users\\" + username + "\\");
		folder.mkdirs();
	}

	/**
	 * creates folder for users that have none and deletes superfluous folders
	 * 
	 * TODO add to draft
	 */
	private void organizeFolders() {
		for (User u : users) {
			File userFolder = new File(".\\users\\" + u.getName() + "\\");
			if (!userFolder.exists()) {
				createUserFolder(u.getName());
			}
		}

		File userDir = new File(".\\users\\");
		String[] directories = userDir.list();
		for (String s : directories) {
			if (!isExistingUser(s)) {
				File file = new File(userDir + "\\" + s);
				deleteDirectory(file);
			}
		}

	}

	/**
	 * deletes a directory recursively
	 * 
	 * TODO add to draft
	 * 
	 * @param f
	 *            the directory to delete
	 */
	private void deleteDirectory(File f) {
		if (f.isDirectory()) {
			for (File c : f.listFiles()) {
				deleteDirectory(c);
			}
		}
		f.delete();
	}
}
